﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using ST.Buz.Base.Entity;
using ST.Buz.Service;
using ST.Common.Data;
using ST.Common.Util;
using ST.Common.Util.Model;
using ST.Common.Util.Mvc;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;

namespace ST.Buz.Web.Controllers
{
	[Route("sys/ue")]
	public class SysUEController : MyBaseController
	{
		/// <summary>
		/// 上传文件大小限制
		/// </summary>
		private static int MAX_FILE_SIZE = 10485760;//10M

		private readonly IServiceSysAttachment service;

		public SysUEController(IServiceSysAttachment _service,
			ILogger<SysUEController> _logger) : base(_logger)
		{
			service = _service;
		}

		#region 基础方法
		public IActionResult Index([FromQuery]string action)
		{
			switch (action)
			{
				case "config":
					return Config();
				case "uploadimage":
					return Upload("image");
				case "uploadfile":
					return Upload("file");
				case "listimage":
					return ListImage();
				default:
					return new EmptyResult();
			}
		}

		private ActionResult ListImage()
		{
			try
			{
				List<string> lstImg = new List<string>();
				string[] files = Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot\\upload"));
				foreach (string file in files)
				{
					lstImg.Add("/upload/" + Path.GetFileName(file));
				}
				//System.IO命名空间中存在Directory类，提供了获取应用程序运行当前目录的静态方法GetCurrentDirectory，
				//但根据.net core的设计，此方法不是真正的获取应用程序的当前方法，而是执行dotnet命令所在目录，
				var ret = new
				{
					state = "SUCCESS",
					list = lstImg,
					start = 0,
					size = 20,
					total = files.Length
				};
				return Json(ret);
			}
			catch (Exception ex)
			{
				logger.LogError(ex, "读取上传目录文件列表出错");
				var ret = new
				{
					state = ex.Message,
				};
				return Json(ret);
			}
		}

		private ActionResult Upload(string fileType)
		{
			string callback = Request.Query["callback"];
			try
			{
				string[] validExtensions = null;
				switch (fileType)
				{
					case "image":
						validExtensions = new string[] { ".jpg", ".jpeg", ".bmp", ".png", ".gif" };
						break;
					case "doc":
						validExtensions = new string[] { ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".wps", ".pdf" };
						break;
					case "file":
						validExtensions = new string[] { ".7z", ".zip", ".rar" };
						break;
					default:
						validExtensions = new string[] { ".jpg", ".jpeg", ".bmp", ".png", ".gif", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".wps", ".pdf", ".7z", ".zip", ".rar" };
						break;
				}
				if (Request.Form.Files == null || Request.Form.Files.Count == 0)
				{
					throw new BuzException("请选择要上传的文件");
				}
				IFormFile file = Request.Form.Files[0];
				if (file.Length == 0)
				{
					throw new BuzException("不能上传空文件");
				}
				string fileExt = Path.GetExtension(file.FileName);
				if (Array.IndexOf(validExtensions, fileExt) < 0)
				{
					throw new BuzException("不支持该文件格式");
				}
				if (file.Length > MAX_FILE_SIZE)
				{
					throw new BuzException("文件大小超出限制（" + MAX_FILE_SIZE + "）");
				}
				UserSession userSession = GetSessionFromRequest();

				string fileName = IDGenerator.NextRand32(userSession.SessionType, userSession.SessionID) + fileExt;
				string fileUrl = "/upload/" + fileName;
				string fileDir = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/upload");
				if (!Directory.Exists(fileDir))
				{
					Directory.CreateDirectory(fileDir);
				}
				string filePath = Path.Combine(fileDir, fileName);
				using (FileStream fs = new FileStream(filePath, FileMode.CreateNew))
				{
					file.CopyTo(fs);
				}

				SysAttachmentDetail info = new SysAttachmentDetail();
				//info.url = fileUrl;
				info.url = HttpContextHelper.GetRequestDomainBase(Request) + fileUrl;
				info.size = (int)file.Length;
				info.original = file.FileName;
				info.title = file.FileName;
				info.type = fileType;
				info.state = "SUCCESS";
				if (string.IsNullOrEmpty(callback))
				{
					return Json(info);
				}
				else
				{
					return Content(callback + "(" + Json(info) + ")");
				}
			}
			catch (AuthException ex)
			{
				logger.LogError(ex, "解析请求头部验证信息出错");
				SysAttachmentDetail info = new SysAttachmentDetail();
				info.state = "Failed";
				info.error = ex.Message;
				if (string.IsNullOrEmpty(callback))
				{
					return Json(info);
				}
				else
				{
					return Content(callback + "(" + Json(info) + ")");
				}
			}
			catch (BuzException ex)
			{
				SysAttachmentDetail info = new SysAttachmentDetail();
				info.state = "Failed";
				info.error = ex.Message;
				if (string.IsNullOrEmpty(callback))
				{
					return Json(info);
				}
				else
				{
					return Content(callback + "(" + Json(info) + ")");
				}
			}
			catch (Exception ex)
			{
				logger.LogError(ex, "上传文件出错");
				SysAttachmentDetail info = new SysAttachmentDetail();
				info.state = "Failed";
				info.error = ex.Message;
				if (string.IsNullOrEmpty(callback))
				{
					return Json(info);
				}
				else
				{
					return Content(callback + "(" + Json(info) + ")");
				}
			}
		}

		/// <summary>
		/// 返回UEditor相关配置信息
		/// </summary>
		/// <returns></returns>
		private ActionResult Config()
		{
			var config = new
			{
				/* 上传图片配置项 */
				imageActionName = "uploadimage", /* 执行上传图片的action名称 */
				imageFieldName = "upfile", /* 提交的图片表单名称 */
				imageMaxSize = 2048000, /* 上传大小限制，单位B */
				imageAllowFiles = new string[] { ".png", ".jpg", ".jpeg", ".gif", ".bmp" }, /* 上传图片格式显示 */
				imageCompressEnable = true, /* 是否压缩图片,默认是true */
				imageCompressBorder = 1600, /* 图片压缩最长边限制 */
				imageInsertAlign = "none", /* 插入的图片浮动方式 */
				imageUrlPrefix = "", /* 图片访问路径前缀 */
				imagePathFormat = "upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
																				/* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
																				/* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
																				/* {time} 会替换成时间戳 */
																				/* {yyyy} 会替换成四位年份 */
																				/* {yy} 会替换成两位年份 */
																				/* {mm} 会替换成两位月份 */
																				/* {dd} 会替换成两位日期 */
																				/* {hh} 会替换成两位小时 */
																				/* {ii} 会替换成两位分钟 */
																				/* {ss} 会替换成两位秒 */
																				/* 非法字符 \ : * ? " < > | */
																				/* 具请体看线上文档: fex.baidu.com/ueditor/#use-format_upload_filename */

				/* 涂鸦图片上传配置项 */
				scrawlActionName = "uploadscrawl", /* 执行上传涂鸦的action名称 */
				scrawlFieldName = "upfile", /* 提交的图片表单名称 */
				scrawlPathFormat = "upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
				scrawlMaxSize = 2048000, /* 上传大小限制，单位B */
				scrawlUrlPrefix = "", /* 图片访问路径前缀 */
				scrawlInsertAlign = "none",

				/* 截图工具上传 */
				snapscreenActionName = "uploadimage", /* 执行上传截图的action名称 */
				snapscreenPathFormat = "upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
				snapscreenUrlPrefix = "", /* 图片访问路径前缀 */
				snapscreenInsertAlign = "none", /* 插入的图片浮动方式 */

				/* 抓取远程图片配置 */
				catcherLocalDomain = new string[] { "127.0.0.1", "localhost", "img.baidu.com" },
				catcherActionName = "catchimage", /* 执行抓取远程图片的action名称 */
				catcherFieldName = "source", /* 提交的图片列表表单名称 */
				catcherPathFormat = "upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
				catcherUrlPrefix = "", /* 图片访问路径前缀 */
				catcherMaxSize = 2048000, /* 上传大小限制，单位B */
				catcherAllowFiles = new string[] { ".png", ".jpg", ".jpeg", ".gif", ".bmp" }, /* 抓取图片格式显示 */

				/* 上传视频配置 */
				videoActionName = "uploadvideo", /* 执行上传视频的action名称 */
				videoFieldName = "upfile", /* 提交的视频表单名称 */
				videoPathFormat = "upload/video/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
				videoUrlPrefix = "", /* 视频访问路径前缀 */
				videoMaxSize = 102400000, /* 上传大小限制，单位B，默认100MB */
				videoAllowFiles = new string[]{
					".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
					".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"
				}, /* 上传视频格式显示 */

				/* 上传文件配置 */
				fileActionName = "uploadfile", /* controller里,执行上传视频的action名称 */
				fileFieldName = "upfile", /* 提交的文件表单名称 */
				filePathFormat = "upload/file/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
				fileUrlPrefix = "", /* 文件访问路径前缀 */
				fileMaxSize = 51200000, /* 上传大小限制，单位B，默认50MB */
				fileAllowFiles = new string[]{
					".png", ".jpg", ".jpeg", ".gif", ".bmp",
					".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
					".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
					".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
					".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
				}, /* 上传文件格式显示 */

				/* 列出指定目录下的图片 */
				imageManagerActionName = "listimage", /* 执行图片管理的action名称 */
				imageManagerListPath = "upload/image", /* 指定要列出图片的目录 */
				imageManagerListSize = 20, /* 每次列出文件数量 */
				imageManagerUrlPrefix = "", /* 图片访问路径前缀 */
				imageManagerInsertAlign = "none", /* 插入的图片浮动方式 */
				imageManagerAllowFiles = new string[] { ".png", ".jpg", ".jpeg", ".gif", ".bmp" }, /* 列出的文件类型 */

				/* 列出指定目录下的文件 */
				fileManagerActionName = "listfile", /* 执行文件管理的action名称 */
				fileManagerListPath = "upload/file", /* 指定要列出文件的目录 */
				fileManagerUrlPrefix = "", /* 文件访问路径前缀 */
				fileManagerListSize = 20, /* 每次列出文件数量 */
				fileManagerAllowFiles = new string[]{
					".png", ".jpg", ".jpeg", ".gif", ".bmp",
					".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
					".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
					".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
					".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
				} /* 列出的文件类型 */
			};
			return Json(config);
		}
		#endregion

	}
}